package com.example.design.sercive;

import com.example.design.item.composite.AbstractProductItem;
import com.example.design.item.composite.ProductComposite;
import com.example.design.item.vistor.AddItemVisitor;
import com.example.design.item.vistor.RemoveItemVisitor;
import com.example.design.pojo.ProductItem;
import com.example.design.repo.ProductItemRepository;
import com.example.design.utils.RedisUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Transactional
@Service
public class ProductItemService {
    @Resource
    private ProductItemRepository productItemRepository;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private AddItemVisitor addItemVisitor;

    @Resource
    private RemoveItemVisitor removeItemVisitor;


    public ProductComposite findAllItems(){
        //先从 Redis 查询缓存，如果不为空，直接返回即可
        Object caccheItems = redisUtils.get("items");
        if (caccheItems != null){
            return (ProductComposite) caccheItems;
        }
        List<ProductItem> all = productItemRepository.findAll();
        ProductComposite items = buildProductComposite(all);
        if (items == null){
            throw new UnsupportedOperationException("没有找到任何商品");
        }
        redisUtils.set("items",items);
        return items;
    }



    private ProductComposite buildProductComposite(List<ProductItem> all) {
        ArrayList<ProductComposite> composites = new ArrayList<>(all.size());
        all.forEach(
                abItem-> composites.add(ProductComposite.builder().
                        id(abItem.getId()).
                        name(abItem.getName()).
                        pid(abItem.getPid()).
                        build())
        );
        Map<Integer,List<ProductComposite>> gruopingList = composites.stream().collect(Collectors.groupingBy(ProductComposite::getPid));
     /*   composites.stream().forEach(item ->{
            List<ProductComposite> list = gruopingList.get(item.getId());
            item.setChild(list == null ? new ArrayList<>() : list.stream().map(AbstractProductItem.class::cast).collect(Collectors.toList()));
        });*/
        composites.forEach(item ->{
            List<ProductComposite> list = gruopingList.get(item.getId());
            item.setChild(list == null ? new ArrayList<>() : list.stream().map(AbstractProductItem.class::cast).collect(Collectors.toList()));
        });
        return composites.size() == 0 ? null : composites.get(0);
    }



    public ProductComposite addItem(ProductItem productItem){
        String name = productItem.getName();
        int pid = productItem.getPid();
        //先更新数据库
        productItemRepository.addItem(name, pid);
        //通过访问者模式访问树形数据结构,并添加新的商品类目
        ProductComposite addItem = ProductComposite.builder().id(productItemRepository.findByNameAndPid(name, pid).getId())
                .name(name)
                .pid(pid)
                .child(new ArrayList<>())
                .build();
        ProductComposite update = addItemVisitor.visit(addItem);
        redisUtils.set("items",update);
        return update;
    }


    public ProductComposite delItem(ProductComposite productComposite){
        int id = productComposite.getId();
        int pid = productComposite.getPid();
        String name = productComposite.getName();
        List<AbstractProductItem> child = productComposite.getChild();

        //先更新数据库
        productItemRepository.delItem(productComposite.getId());
        //通过访问者模式访问树形数据结构,并删除商品类目
        ProductComposite delItem = ProductComposite.builder().id(id)
                .name(name)
                .pid(pid)
                .child(child)
                .build();
        //此处可以做重试机制
        ProductComposite update = removeItemVisitor.visit(delItem);
        redisUtils.set("items",update);
        return update;
    }



}
